package com.tbit.uqbike.client.service.ordertrace;

import com.tbit.uqbike.client.ordertrace.OrderStage;
import com.tbit.uqbike.client.ordertrace.OrderStateMachine;
import com.tbit.uqbike.client.ordertrace.Snapshot;
import com.tbit.uqbike.client.ordertrace.StateTransitionComponent;
import com.tbit.uqbike.client.pojo.ordertrace.OrderEvent;
import com.tbit.uqbike.client.pojo.ordertrace.OrderEventDetail;
import com.tbit.uqbike.client.service.ordertrace.business.AccountInfo;
import com.tbit.uqbike.client.service.ordertrace.business.ExtendedInfo;
import com.tbit.uqbike.client.service.ordertrace.business.OrderInfo;
import com.tbit.uqbike.client.service.ordertrace.business.UserInfo;
import lombok.Builder;
import lombok.Data;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单事件业务对象
 *
 *
 * @author <a href="mailto:chen.chaoxiong@tbit.com.cn">ChenChaoXiong</a>
 * @since 2024/7/4
 */
@Data
@Builder
public class OrderEventBO {

    private Long id;

    private String traceId;

    /**
     * 每次请求状态机的拓展信息
     * key: requestId
     */
    private Map<String, ExtendedInfo> extendedInfoMap;

    private OrderStateMachine orderStateMachine;

    private AccountInfo accountInfo;

    private OrderInfo orderInfo;

    private UserInfo userInfo;

    public OrderEvent toOrderEvent() {
        OrderEvent orderEvent = new OrderEvent();
        orderEvent.setId(id);
        orderEvent.setTraceId(traceId);
        orderEvent.setStage(orderStateMachine.getStage()
                                             .getName());

        //仅在当前对象中的accountInfo中的brandId和accountId不为空时才设置
        if (accountInfo != null) {
            if (accountInfo.getBrandId() != null){
                orderEvent.setBrandId(accountInfo.getBrandId());
            }
            if (accountInfo.getAccountId() != null){
                orderEvent.setAccountId(accountInfo.getAccountId());
            }
        }

        //仅在当前对象中的orderInfo中的orderNo和machineId不为空时才设置
        if (userInfo != null) {
            if (userInfo.getUserId() != null){
                orderEvent.setUserId(userInfo.getUserId());
            }
            if (userInfo.getUserPhone() != null){
                orderEvent.setUserPhone(userInfo.getUserPhone());
            }
        }

        //仅在当前对象中的orderInfo中的orderNo和machineId不为空时才设置
        if (orderInfo != null) {
            if (orderInfo.getOrderNo() != null){
                orderEvent.setOrderNo(orderInfo.getOrderNo());
            }
            if (orderInfo.getMachineId() != null){
                orderEvent.setMachineId(orderInfo.getMachineId());
            }
        }
        return orderEvent;
    }

    public List<OrderEventDetail> toOrderEventDetailList() {
        List<Snapshot> snapshots = orderStateMachine.getSnapshots();
        Assert.notNull(snapshots, "snapshots must not be null");

        return snapshots.stream()
                 .map(this::fromSnapshot)
                .collect(Collectors.toList());
    }

    private OrderEventDetail fromSnapshot(Snapshot snapshot) {
        OrderEventDetail orderEventDetail = new OrderEventDetail();
        orderEventDetail.setBrandId(accountInfo.getBrandId());
        orderEventDetail.setAccountId(accountInfo.getAccountId());
        orderEventDetail.setTraceId(traceId);
        orderEventDetail.setOrderNo(orderInfo.getOrderNo());
        orderEventDetail.setMachineId(orderInfo.getMachineId());
        orderEventDetail.setUserId(userInfo.getUserId());
        orderEventDetail.setBeforeStage(snapshot.getPreviousStage().getName());
        orderEventDetail.setAfterStage(snapshot.getCurrentStage().getName());

        orderEventDetail.setEventType(snapshot.getEvent()
                                              .getEventType());


        ExtendedInfo extendedInfo = extendedInfoMap.get(snapshot.getRequestId());
        if (extendedInfo != null) {
            orderEventDetail.setMessage(extendedInfo.getMessage());
            orderEventDetail.setBusinessInfo(extendedInfo.getBusinessInfo());
            orderEventDetail.setEventTime(extendedInfo.getEventTime());
            orderEventDetail.setDetail(extendedInfo.getDetail());
            orderEventDetail.setEventDesc(extendedInfo.getEventDesc());
        }
        if (orderEventDetail.getEventDesc() == null){
            orderEventDetail.setEventDesc("");
        }

        return orderEventDetail;
    }

    public static OrderEventBO fromOrderEvent(OrderEvent orderEvent, StateTransitionComponent stateTransitionComponent){
        OrderStage orderStage = new OrderStage(orderEvent.getStage());
        OrderStateMachine stateMachine = OrderStateMachine.create(orderStage, stateTransitionComponent, orderEvent.getTraceId());
        AccountInfo accountInfo = AccountInfo.builder()
                .brandId(orderEvent.getBrandId())
                .accountId(orderEvent.getAccountId())
                .build();
        OrderInfo orderInfo = OrderInfo.builder()
                .orderNo(orderEvent.getOrderNo())
                .machineId(orderEvent.getMachineId())
                .build();
        UserInfo userInfo = UserInfo.builder()
                .userId(orderEvent.getUserId())
                .userPhone(orderEvent.getUserPhone())
                .build();


        return OrderEventBO.builder()
                .id(orderEvent.getId())
                .traceId(orderEvent.getTraceId())
                .orderStateMachine(stateMachine)
                .accountInfo(accountInfo)
                .orderInfo(orderInfo)
                .userInfo(userInfo)
                .build();
    }

}
